package com.hexinfo.dmpro.sparing.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileAppender;
import cn.hutool.core.util.ObjectUtil;
import com.hexinfo.dmpro.common.model.MessageCenter;
import com.hexinfo.dmpro.common.service.MessageCenterService;
import com.hexinfo.dmpro.common.utils.ScanCommonConstants;
import com.hexinfo.dmpro.sparing.async.AsyncTask;
import com.hexinfo.dmpro.sparing.dto.CreateTableDTO;
import com.hexinfo.dmpro.sparing.service.CreateTableService;
import com.hexinfo.dmpro.sparing.service.FutureService;
import com.hexinfo.dmpro.sparing.service.HiveToOracleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class CreateTableServiceImpl implements CreateTableService {

    private final HiveToOracleService hiveToOracleService;
    private final MessageCenterService messageCenterService;
    private final AsyncTask asyncTask;
    private final FutureService futureService;
    @Value("${heatBackup.logPath}")
    private String logPath;
    /**
     * @Method createTableDifference
     * @Param
     * @Return java.lang.String
     * @Description 补充自动化建表
     * @Author Wei MinYe
     * @Date 2024/3/28 17:03
     * @Version V1.0
     */
    @Override
    public String createTableDifference(){
        Map<String,Integer> intMap = new HashMap<>();
        intMap.put("SB",0);
        intMap.put("YWC",0);
        //获取日志路径
        String logFilePath = path();
        //金桥库表信息
        List<CreateTableDTO> listJQ = hiveToOracleService.hiveQueryLibraryTable(ScanCommonConstants.ClusterName.JQ.value);
        //万国库表信息
        List<CreateTableDTO> listWG = hiveToOracleService.hiveQueryLibraryTable(ScanCommonConstants.ClusterName.WG.value);
        //差集
        List<CreateTableDTO> list = listJQ.stream()
                .filter(a -> listWG.stream().noneMatch(b -> b.getDbTableName().equals(a.getDbTableName())))
                .collect(Collectors.toList());
        if(ObjectUtil.isEmpty(list)){
            return "暂无差集库表信息";
        }
        //建表sql集合
        //消息中心
        MessageCenter mess = new MessageCenter();
        mess.setMenu(ScanCommonConstants.ClusterName.SJRB.value);
        mess.setOperator("admin");
        mess.setDataType(ScanCommonConstants.ClusterName.JXZ.value);
        mess.setMessageSubject(ScanCommonConstants.ClusterName.KJSJTB.value);
        mess.setMessageWeight(ScanCommonConstants.ClusterName.ONE.value);
        mess.setLogPath(logFilePath);
        messageCenterService.save(mess);
        FileAppender heatlog = new FileAppender(new File(logFilePath), 100, true);
        heatlog.append(logTime("【自动化建表开始】 所建表数量为："+list.size()));
        heatlog.append(logTime("【表名列表】"));
        for (CreateTableDTO tableDTO: list) {
            heatlog.append(logTime(tableDTO.getTableName()+"\n"));
        }
        List<Future<Map<String,Object>>> futures = new ArrayList<>();//存线程的返回结果
        for (CreateTableDTO tableDTO: list) {
            //以下调用会启动线程进行执行，多线程并发
            Future<Map<String,Object>> res = asyncTask.forCreateTable(tableDTO,heatlog,intMap);
            futures.add(res);
        }
        //会等待所有线程都执行结束，拿到结果
        futureService.futureResult(futures);
        heatlog.append(logTime("【自动化建表结束】"));
        heatlog.flush();
        mess.setDataType(ScanCommonConstants.ClusterName.YWC.value);
        messageCenterService.saveOrUpdate(mess);
        if (intMap.get("SB") == 0) {
            return "建表完成";
        }
        return "建表失败 失败数量："+intMap.get("SB");
    }

    public String path() {
        return logPath.replace("{date}", DateUtil.format(DateUtil.date(), "yyyyMMdd"))
                + "CT" + "/" + "createTable" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss") + ".txt";
    }
    private String logTime(String str) {
        return "["+ DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")+"]" +str;
    }

}
